using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FiltronASP.Logger;

namespace FiltronASP.Models.DAO
{
    /// <summary>
    /// Klasa dla operacji bazodanowych specyficznych dla tabeli <code>variable_values</code>.
    /// </summary>
    public class VariableValueDAO : Abstracts.AbstractGenericDAO<VariableValue, System.Nullable<int>>,
        Interfaces.IVariableValueDAO
    {
        /// <summary>
        /// Metoda zwracajaca nazwe parametru bedacego kluczem glownym tabeli.
        /// </summary>
        /// <returns>nazwa klucza glownego</returns>
        protected override string GetKeyProperty()
        {
            return "variable_value_id";
        }

        /// <summary>
        /// Pobieranie listy obiektów na podstawie strony.
        /// </summary>
        /// <param name="pageId">strona</param>
        /// <returns>Lista rekordów o zadanej stronie</returns>
        public IQueryable<VariableValue> FindByPage(int pageId)
        {
            if (pageId.Equals(0))
            {
                return null;
            }   //if
            try
            {
                IQueryable<VariableValue> variables = this._cmsEntitiesDataContext.VariableValues.Where(
                    varv => varv.page_id.Equals(pageId)
                        );

                if (!(variables.Any()))
                {
                    return null;
                }   //if
                return variables;
            }   //try
            catch (Exception ex)
            {
                MyLogger.Log(ex);
            }   //catch
            return null;
        }

        /// <summary>
        /// Usuwanie obiektów na podstawie strony.
        /// </summary>
        /// <param name="pageId">strona</param>
        /// <returns>true w przypadku usunięcia, false w przypadku nie odnalezienia rekordów</returns>
        public bool DeleteByPage(int pageId)
        {
            if (pageId.Equals(0))
            {
                return false;
            }   //if
            try
            {
                IQueryable<VariableValue> values = this._cmsEntitiesDataContext.VariableValues.Where(
                    page => page.page_id.Equals(pageId)
                        );
                if (!(values.Any()))
                {
                    return false;
                }
                foreach (VariableValue i in values)
                {
                    this._cmsEntitiesDataContext.VariableValues.DeleteOnSubmit(i);
                }
                try
                {
                    _cmsEntitiesDataContext.SubmitChanges();
                    return true;
                }
                catch (Exception ex)
                {
                    MyLogger.Log(ex);
                }   //catch
                //if

            }   //try
            catch (Exception ex)
            {
                MyLogger.Log(ex);
            }   //catch
            return false;
        }

        /// <summary>
        /// Pobieranie obiektu na podstawie zmiennej i strony.
        /// </summary>
        /// <param name="variableId">zmienna</param>
        /// <param name="pageId">strona</param>
        /// <returns>Lista rekordów o zadanej zmiennej i stronie</returns>
        public VariableValue FindByVariableAndPage(int variableId, int pageId)
        {
            if (pageId.Equals(0) || variableId.Equals(0))
            {
                return null;
            }   //if
            try
            {
                return this._cmsEntitiesDataContext.VariableValues.SingleOrDefault(
                    varv => varv.variable_id.Equals(variableId) && varv.page_id.Equals(pageId)
                );
            }   //try
            catch (Exception ex)
            {
                MyLogger.Log(ex);
            }   //catch
            return null;
        }

        /// <summary>
        /// Pobieranie obiektu na podstawie zmiennej i strony.
        /// </summary>
        /// <param name="variableId">zmienna</param>        
        /// <returns>Lista rekordów o zadanej zmiennej</returns>
        public IQueryable<VariableValue> FindByVariableId(int variableId)
        {
            if (variableId.Equals(0))
            {
                return null;
            }   //if
            try
            {
                return this._cmsEntitiesDataContext.VariableValues.Where(
                    varv => varv.variable_id.Equals(variableId)
                );
            }   //try
            catch (Exception ex)
            {
                MyLogger.Log(ex);
            }   //catch
            return null;
        }

        /// <summary>
        /// Pobieranie obiektu na podstawie nazwy zmiennej i strony.
        /// </summary>
        /// <param name="variableName">nazwa zmiennej</param>
        /// <param name="pageId">strona</param>
        /// <returns>Lista rekordów o zadanej nazwie zmiennej i stronie</returns>
        public VariableValue FindByVariableAndPage(string variableName, int pageId)
        {
            if (pageId.Equals(0) || String.IsNullOrEmpty(variableName))
            {
                return null;
            }   //if
            try
            {
                return this._cmsEntitiesDataContext.VariableValues.SingleOrDefault(
                    varv => varv.variable_id.Equals(this._cmsEntitiesDataContext.Variables.SingleOrDefault(
                        vari => vari.variable_name.Equals(variableName) && vari.language_id.Equals(7)).variable_id) &&
                        varv.page_id.Equals(pageId)
                );
            }   //try
            catch (Exception ex)
            {
                MyLogger.Log(ex);
            }   //catch
            return null;
        }

        /// <summary>
        /// Pobieranie obiektu na podstawie nazwy zmiennej i strony.
        /// </summary>
        /// <param name="variableName">nazwa zmiennej</param>
        /// <param name="pageId">strona</param>
        /// <returns>Lista rekordów o zadanej nazwie zmiennej i stronie</returns>
        public VariableValue FindByVariableAndPage(string variableName, int pageId, int languageId)
        {
            if (pageId.Equals(0) || String.IsNullOrEmpty(variableName))
            {
                return null;
            }   //if
            try
            {
                return this._cmsEntitiesDataContext.VariableValues.SingleOrDefault(
                    varv => varv.variable_id.Equals(this._cmsEntitiesDataContext.Variables.SingleOrDefault(
                        vari => vari.variable_name.Equals(variableName) && vari.language_id.Equals(languageId)).variable_id) &&
                        varv.page_id.Equals(pageId)
                );
            }   //try
            catch (Exception ex)
            {
                MyLogger.Log(ex);
            }   //catch
            return null;
        }

        /// <summary>
        /// Pobieranie listy obiektów na podstawie języka.
        /// </summary>
        /// <param name="languageId">język</param>
        /// <returns>Lista rekordów o zadanym języku</returns>
        public IQueryable<VariableValue> FindByLanguage(int languageId)
        {
            if (languageId.Equals(0))
            {
                return null;
            }   //if
            try
            {
                IQueryable<VariableValue> variables = this._cmsEntitiesDataContext.VariableValues.Where(
                    varv => (this._cmsEntitiesDataContext.Variables.Where(
                        vari => vari.language_id.Equals(languageId)).Select(la => la.variable_id).Contains(varv.variable_id)
                        )
                        );

                if (!(variables.Any()))
                {
                    return null;
                }   //if
                return variables;
            }   //try
            catch (Exception ex)
            {
                MyLogger.Log(ex);
            }   //catch
            return null;
        }

        /// <summary>
        /// Wstawianie listy obiektów na podstawie jezyka.
        /// </summary>
        /// <param name="defaultLanguageId">domyslny jezyk</param>
        /// <param name="newLanguageId">nowy jezyk</param>
        /// <returns>true jesli sie udalo, false wpp</returns>
        public bool InsertForNewLanguage(int defaultLanguageId, int newLanguageId)
        {
            if (defaultLanguageId.Equals(0) || newLanguageId.Equals(0))
            {
                return false;
            }   //if
            try
            {
                IQueryable<VariableValue> variableValues = this.FindByLanguage(defaultLanguageId);
                VariableDAO _variableDAO = new VariableDAO();
                TemplateDAO _templateDAO = new TemplateDAO();
                PageDAO _pageDAO = new PageDAO();
                if (variableValues == null)
                {
                    return true;
                }   //if
                if (!(variableValues.Any()))
                {
                    return true;
                }   //if
                foreach (VariableValue varVa in variableValues)
                {
                    Variable oldVariable = _variableDAO.FindByPK(varVa.variable_id);
                    if (oldVariable == null)
                    {
                        return false;
                    }
                    Template oldTemp = _templateDAO.FindByPK(oldVariable.template_id);
                    if (oldTemp == null)
                    {
                        return false;
                    }
                    Template newTemp = _templateDAO.FindByLangAndName(newLanguageId, oldTemp.template_name);
                    if (newTemp == null)
                    {
                        return false;
                    }
                    Variable newVariable = _variableDAO.FindByTemplateAndLanguageAndName(newTemp.template_id, newLanguageId, oldVariable.variable_name);
                    if (newVariable == null)
                    {
                        return false;
                    }
                    Page oldPage = _pageDAO.FindByPK(varVa.page_id);
                    if (oldPage == null)
                    {
                        return false;
                    }
                    Page newPage = _pageDAO.FindByLanguageAndAlliasAndLink(newLanguageId, oldPage.page_alias, oldPage.page_link);
                    if (newPage == null)
                    {
                        return false;
                    }
                    VariableValue variableValueToInsert = new VariableValue();
                    variableValueToInsert.page_id = newPage.page_id;
                    variableValueToInsert.variable_id = newVariable.variable_id;
                    variableValueToInsert.variable_value_created = DateTime.Now;
                    variableValueToInsert.variable_value_created_by_id = varVa.variable_value_created_by_id;
                    variableValueToInsert.variable_value_modified = DateTime.Now;
                    variableValueToInsert.variable_value_modified_by_id = varVa.variable_value_modified_by_id;
                    variableValueToInsert.variable_value_published = varVa.variable_value_published;
                    variableValueToInsert.variable_value = varVa.variable_value;
                    this.Add(variableValueToInsert);
                }

            }   //try
            catch (Exception ex)
            {
                MyLogger.Log(ex);
            }   //catch
            return true;
        }

        /// <summary>
        /// Usuwanie obiektow po jezyku.
        /// </summary>
        /// <param name="languageId">jezyk</param>
        /// <returns>true dla sukcesu, false w przeciwnym razie</returns>
        public bool DeleteByLanguage(int languageId)
        {
            if (languageId.Equals(0))
            {
                return false;
            }   //if
            try
            {
                List<int> ids = new List<int>();
                IQueryable<VariableValue> variableValues = this.FindByLanguage(languageId);
                if (variableValues == null)
                {
                    return true;
                }   //if
                if (!(variableValues.Any()))
                {
                    return true;
                }   //if
                foreach (VariableValue varVa in variableValues)
                {
                    this._cmsEntitiesDataContext.VariableValues.DeleteOnSubmit(varVa);
                }      
                try
                {
                    _cmsEntitiesDataContext.SubmitChanges();
                    
                }
                catch (Exception ex)
                {
                    MyLogger.Log(ex);
                }   //catch
                return true;
            }   //try
            catch (Exception ex)
            {
                MyLogger.Log(ex);
            }   //catch
            return false;
        }
    }
}
